home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Simple Slideshow / clut_fade 1.2 ƒ / clut_fade 1.2 / fade.c < prev    next >
Encoding:
Text File  |  1994-11-08  |  10.6 KB  |  329 lines  |  [TEXT/KAHL]

  1. /********************************************************************************
  2.  
  3.      PROJECT:    clut_fade.π
  4.      
  5.      FILE:        fade.c
  6.      
  7.      PURPOSE:    'clut' fading functions
  8.      
  9.      ??/??/93    1.0 written by N. Jonas Englund
  10.      07/26/94    1.1 Changes by Mark Womack to allow fading all monitors, only the
  11.                  main monitor, or all monitors except the main monitor.  Cleaned 
  12.                  up the fade.h to hide more structures, and removed almost all global
  13.                  space used (My changes grew the global space by 10 times so I figured
  14.                  it needed to be fixed).  Current code is limited to 10 monitors max,
  15.                  but is easily cofigurable for more if you think you need it.
  16.      10/21/94    Changes by Mark Womack to make pascal friendly, fix < 256 color
  17.                  crasher, cleaned up to make more readable.
  18.      10/24/94    Integrated fade_to_clut function written by Macneil Shonle.
  19.                  Added copy_gdevice_clut function to make it easier to save
  20.                  and restore device clut's.
  21.                   Added fade_to_color function which uses both the fade_to_clut
  22.                   and copy_gdevice_clut functions to fade to a given rgb value.
  23.                 
  24.      =-=-= PLEASE SEE THE README THAT ACCOMPANIED THIS PROJECT FOR DETAILS =-=-=
  25.      
  26.      This software is considered Public Domain. You are free to use it in any
  27.      manner you wish. You are free to upload it to your favorite service, but
  28.      you must post it with the accompanying readme and description files.
  29.      If you use or appreciate it, please let us know!! We all love to get email.
  30.      See the addresses below.
  31.      
  32.      This software is offered 'as is'. The authors are not responsible for any
  33.      damages caused by bugs or defects that might be lurking. But if it blows up
  34.      your monitor, please let us know. If you find any bugs, problems, enhancements,
  35.      please contact us.
  36.      
  37.      Email Addresses:  MarkWomack@aol.com, MacneilS@aol.com, KenLong@aol.com.
  38.  
  39.  ********************************************************************************/
  40.  
  41. //================================= INCLUDES ====================================
  42.  
  43. #include "fade.h"
  44.  
  45. //================================= DEFINES =====================================
  46.  
  47. #define     MAXCOLORS     256     // supports 256 colors max
  48. #define        gMaxDevices    10        // supports only 10 monitors max
  49.  
  50. //================================= TYPEDEFS ====================================
  51.  
  52. typedef struct FadeValues
  53. {
  54.     short    reds[MAXCOLORS];
  55.     short    greens[MAXCOLORS];
  56.     short    blues[MAXCOLORS];
  57. }
  58. FadeValues;
  59.  
  60. //================================= FUNCTIONS ===================================
  61.  
  62. static void copy_cluts    (GDHandle, CTabHandle*, CTabHandle*, short);
  63. static void calc_fade    (long, CTabHandle, FadeValues*);
  64. static void fade_out    (long, CTabHandle, FadeValues);
  65. static void fade_in        (long, CTabHandle, CTabHandle, FadeValues);
  66. static void black_out    (CTabHandle);
  67. static void restore_clut(CTabHandle, CTabHandle);
  68.  
  69. //===== PUBLIC FUNCTIONS =====//
  70.  
  71. /********************************** fade_to_black ******************************/
  72. pascal void fade_to_black(long numSteps, short fadeFlags, Boolean fadeOut)
  73. {
  74. GDHandle     oldDev, hGD;
  75. GDHandle    gdHdls[gMaxDevices];    // list of valid graphic devices
  76. FadeValues    rgbs[gMaxDevices];        // fade values
  77. CTabHandle     gFade[gMaxDevices],        // 'clut' to alter with fading functions
  78.             gOrig[gMaxDevices];        // 'clut' to hold a copy of original
  79. short        x,numDevices,stepCount;
  80.     
  81.     // initialize
  82.     oldDev = GetGDevice();
  83.     hGD = (!!(fadeFlags & fadeMainOnly != 0)) ? GetMainDevice() : GetDeviceList();
  84.     numDevices = 0;
  85.     
  86.     // make a list of the affected gdevices
  87.     while (hGD && numDevices < gMaxDevices)
  88.     {
  89.         // skip main device if fadeAllButMain flag
  90.         if (TestDeviceAttribute(hGD,mainScreen) && (!!(fadeFlags & fadeAllButMain)))
  91.         {
  92.             hGD = (GDHandle)(*hGD)->gdNextGD;
  93.             continue;
  94.         }
  95.         
  96.         if (TestDeviceAttribute(hGD,screenDevice))
  97.         {
  98.             gdHdls[numDevices] = hGD;
  99.             numDevices++;
  100.         }
  101.  
  102.         // stop now if only fading main device
  103.         if (!!(fadeFlags & fadeMainOnly != 0))
  104.             break;
  105.             
  106.         hGD = (GDHandle)(*hGD)->gdNextGD;
  107.     }
  108.     
  109.     // calculate the fade cluts for each device
  110.     for (x = 0; x < numDevices; x++)
  111.     {            
  112.         SetGDevice(gdHdls[x]);
  113.         copy_cluts(gdHdls[x], &gFade[x], &gOrig[x], x);
  114.         calc_fade(numSteps, gFade[x], &rgbs[x]);
  115.     }
  116.  
  117.      // fade each device
  118.      // I know this is unreadable (dontcha love C?), the idea is to count down on
  119.      // fadeout and count up on fade in.
  120.      for (stepCount = fadeOut ? numSteps : 0; fadeOut ? stepCount >= 0 : stepCount < numSteps; fadeOut ? stepCount-- : stepCount++)
  121.      {
  122.          for (x = 0; x < numDevices; x++)
  123.          {
  124.              SetGDevice(gdHdls[x]);
  125.             if (fadeOut)
  126.                 fade_out(stepCount, gFade[x], rgbs[x]);
  127.             else
  128.                 fade_in(stepCount, gFade[x], gOrig[x], rgbs[x]);
  129.         }
  130.     }
  131.     
  132.     // restore each devices clut, and dispose of temp memory
  133.     for (x = 0; x < numDevices; x++)
  134.     {
  135.         SetGDevice(gdHdls[x]);
  136.         restore_clut(gFade[x], gOrig[x]);
  137.         DisposeHandle((Handle)gOrig[x]);
  138.     }        
  139.     
  140.     // set original device
  141.     SetGDevice(oldDev);    
  142. }
  143.  
  144. /*********************************** fade_to_clut *******************************/
  145. pascal void fade_to_clut(long numSteps, CTabHandle destTab, GDHandle aGDevice )
  146. {
  147. CTabHandle    srcTab = (**(**aGDevice).gdPMap).pmTable; // get the monitor’s current clut
  148. long        redDelta[MAXCOLORS];    // We want the range for each color to be of an
  149. long        greenDelta[MAXCOLORS];    // unsigned short, but we need negative numbers.
  150. long        blueDelta[MAXCOLORS];    // So these longs are the solution.
  151. long        difference;                // used to clear up clutter in the code
  152. long        i;                        // to cycle trough for loops
  153. long        colorIndex;                // to cycle through arrays
  154. GDHandle    oldGDevice;
  155.  
  156.     oldGDevice = GetGDevice(); // save the old
  157.  
  158.     SetGDevice( aGDevice );  // set it to the monitor to be faded
  159.  
  160.     /**** Set up the deltas ****/
  161.     for( i=0; i <= (**destTab).ctSize; i++ )
  162.     {    /*    This is what I am thinking: take the difference between the two colors and divide
  163.             it by the number of steps (numSteps). So we will have a number that can be added
  164.             to the source numSteps times and have it end up equaling the destination.
  165.         */
  166.   
  167.         difference = ( (long)(**srcTab).ctTable[i].rgb.red - (long)(**destTab).ctTable[i].rgb.red );
  168.         redDelta[i] = difference / (long)numSteps;
  169.   
  170.           difference = ( (long)(**srcTab).ctTable[i].rgb.green - (long)(**destTab).ctTable[i].rgb.green );
  171.           greenDelta[i] = difference / (long)numSteps;
  172.   
  173.         difference = ( (long)(**srcTab).ctTable[i].rgb.blue - (long)(**destTab).ctTable[i].rgb.blue );
  174.         blueDelta[i] = difference / (long)numSteps;
  175.     }
  176.  
  177.     /**** Do the fade ****/
  178.     for( i = 0; i < numSteps; i++ )
  179.     {
  180.         for( colorIndex = 0; colorIndex <= (**destTab).ctSize; colorIndex++ )
  181.         { // make the source more and more like the dest
  182.             (**srcTab).ctTable[colorIndex].rgb.red -= redDelta[colorIndex];
  183.             (**srcTab).ctTable[colorIndex].rgb.green -= greenDelta[colorIndex];
  184.             (**srcTab).ctTable[colorIndex].rgb.blue -= blueDelta[colorIndex];
  185.         }
  186.   
  187.         SetEntries( 0, (**srcTab).ctSize, (ColorSpec *)&(**srcTab).ctTable );
  188.     }
  189.  
  190.     SetEntries( 0, (**destTab).ctSize, (ColorSpec *)&(**destTab).ctTable ); // set it to the dest, just in case
  191.     MakeITable( nil, nil, 0 );
  192.  
  193.     SetGDevice( oldGDevice ); // return it back to it’s old state
  194. }
  195.  
  196. pascal void fade_to_color(long numSteps, RGBColor* destColor, GDHandle aGDevice )
  197. {
  198. CTabHandle    newColors;
  199. short        x;
  200.  
  201.     // get copy of the current color table
  202.     copy_gdevice_clut(aGDevice,&newColors);
  203.  
  204.     // make the color table all one color
  205.     for( x = 0; x <= (**newColors).ctSize; x++ )
  206.         (**newColors).ctTable[x].rgb = *destColor;
  207.  
  208.     // fade to the custom color table
  209.     fade_to_clut(numSteps,newColors,aGDevice);
  210.  
  211.     // dispose color table
  212.     DisposeHandle((Handle)newColors);
  213. }
  214.  
  215. pascal void copy_gdevice_clut(GDHandle aGDevice, CTabHandle* copyOfClut)
  216. {
  217. CTabHandle    srcTab = (**(**aGDevice).gdPMap).pmTable; // get the monitor’s current clut
  218.  
  219.     HandToHand((Handle*)&srcTab);
  220.     *copyOfClut = srcTab;
  221. }
  222.  
  223. //===== PRIVATE FUNCTIONS =====//
  224.  
  225. /********************************** copy_cluts **********************************/
  226. static
  227. void copy_cluts(GDHandle hGD, CTabHandle* gFade, CTabHandle* gOrig, short arrayPos)
  228. {    
  229. Handle        gTempH;            //  temporary handle to copy 'clut'
  230.  
  231.     *gFade = (*(*hGD)->gdPMap)->pmTable;
  232.     gTempH = (Handle) (*(*hGD)->gdPMap)->pmTable;
  233.     HandToHand(&gTempH);
  234.     *gOrig = (CTabHandle) gTempH;
  235.     
  236.     HLock((Handle) *gFade);
  237.     HLock((Handle) *gOrig);
  238. }
  239.  
  240. /*********************************** calc_fade **********************************/
  241. static
  242. void calc_fade(long numSteps, CTabHandle gFade, FadeValues *rgbs)
  243. {
  244.     short    i;
  245.     
  246.     for (i = 0; i <= (*gFade)->ctSize; i++)
  247.     {
  248.         rgbs->reds[i]   = (*gFade)->ctTable[i].rgb.red   / numSteps;
  249.         rgbs->greens[i] = (*gFade)->ctTable[i].rgb.green / numSteps;
  250.         rgbs->blues[i]  = (*gFade)->ctTable[i].rgb.blue  / numSteps;
  251.     }
  252. }
  253.  
  254. /*********************************** fade_out ***********************************/
  255. static
  256. void fade_out(long fadeLevel, CTabHandle gFade, FadeValues rgbs)
  257. {
  258.     short     i;
  259.     
  260.     for (i = 0; i <= (*gFade)->ctSize; i++)
  261.     {
  262.         if ((*gFade)->ctTable[i].rgb.red   > rgbs.reds[i])
  263.             (*gFade)->ctTable[i].rgb.red   -= rgbs.reds[i];
  264.         if ((*gFade)->ctTable[i].rgb.green > rgbs.greens[i])
  265.             (*gFade)->ctTable[i].rgb.green -= rgbs.greens[i];
  266.         if ((*gFade)->ctTable[i].rgb.blue  > rgbs.blues[i])
  267.             (*gFade)->ctTable[i].rgb.blue  -= rgbs.blues[i];
  268.     }
  269.     SetEntries(0,  (*gFade)->ctSize, (*gFade)->ctTable);
  270.     
  271.     if (fadeLevel == 0)
  272.         black_out(gFade);
  273. }
  274.  
  275. /************************************ fade_in ***********************************/
  276. static
  277. void fade_in(long fadeLevel, CTabHandle gFade, CTabHandle gOrig, FadeValues rgbs)
  278. {
  279.     short     i;
  280.     
  281.     if (fadeLevel == 0)
  282.         black_out(gFade);
  283.  
  284.     for (i = 0; i <= (*gFade)->ctSize; i++)
  285.     {
  286.         if ((*gFade)->ctTable[i].rgb.red   < (*gOrig)->ctTable[i].rgb.red)
  287.             (*gFade)->ctTable[i].rgb.red   += rgbs.reds[i];
  288.         if ((*gFade)->ctTable[i].rgb.green < (*gOrig)->ctTable[i].rgb.green)
  289.             (*gFade)->ctTable[i].rgb.green += rgbs.greens[i];
  290.         if ((*gFade)->ctTable[i].rgb.blue  < (*gOrig)->ctTable[i].rgb.blue)
  291.             (*gFade)->ctTable[i].rgb.blue  += rgbs.blues[i];
  292.     }
  293.     SetEntries(0, (*gFade)->ctSize, (*gFade)->ctTable);
  294. }
  295.  
  296. /*********************************** black_out **********************************/
  297. static
  298. void black_out(CTabHandle gFade)
  299. {
  300.     short     i;
  301.     
  302.     for (i = 0; i <= (*gFade)->ctSize; i++)
  303.     {
  304.         (*gFade)->ctTable[i].rgb.red   = 0;
  305.         (*gFade)->ctTable[i].rgb.green = 0;
  306.         (*gFade)->ctTable[i].rgb.blue  = 0;
  307.     }
  308.     SetEntries(0, (*gFade)->ctSize, (*gFade)->ctTable);
  309. }
  310.  
  311. /********************************** restore_clut ********************************/
  312. static
  313. void restore_clut(CTabHandle gFade, CTabHandle gOrig)
  314. {
  315.     short     i;
  316.     
  317.     for (i = 0; i <= (*gFade)->ctSize; i++)
  318.     {
  319.         (*gFade)->ctTable[i].rgb.red   = (*gOrig)->ctTable[i].rgb.red;
  320.         (*gFade)->ctTable[i].rgb.green = (*gOrig)->ctTable[i].rgb.green;
  321.         (*gFade)->ctTable[i].rgb.blue  = (*gOrig)->ctTable[i].rgb.blue;
  322.     }
  323.     (*gFade)->ctSeed = GetCTSeed();
  324.     MakeITable(nil, nil, 0);
  325.     
  326.     HUnlock((Handle) gFade);
  327.     HUnlock((Handle) gOrig);
  328. }
  329.